/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package codec.fibonacci;

import java.util.BitSet;

/**
 *
 * @author Douglas
 */
public class DecodeFibonacci extends Fibonacci{

    private char charSaida;
    private int indexBits;
    private int indexFib;
    private boolean ultimoSetado;
    private int numeroChar;
/**
 * AdicionaBitSet.
 * A partir do caracter lido, monta um Array de bits.
 */
    public void adicionaBitSet() {
        bitSet = new BitSet(16);
        int caracterInt = (int) caracter;
        int bitSetIdv = 0;
        int valorCmp;
        for (int i = 15; i >= 0; i--) {
            valorCmp =(int)Math.pow(2, i);
            if (caracterInt >= valorCmp) {
                bitSet.set(bitSetIdv);
                caracterInt -= valorCmp;
            }
            bitSetIdv++;
        }
    }
/**
 * AchouLetra.
 * A partir do que está no array de bits, faz o caminho reverso, recuperando
 * as palavras codificadas. Para cada bit setado, soma o valor do índice da
 * sequencia de fibonacci, se encontrar 2 setados repetidos, achou uma letra.
 * @return 
 * Boolean, indicando se tem alguma letra para extrair 
 */
    public boolean achouLetra() {
        for (int i = indexBits; i <= 15; i++) {
// Condição determinística de que encontrou caracter codificado
            if(bitSet.get(i) && ((i > 0 && bitSet.get(i-1)) || (i == 0 && isUltimoSetado())) && indexFib!=0){
// Move o caracter decodificado para ponte de saída e inicializa variáveis
// Para começar nova extração                
                setCharSaida((char)getNumeroChar());
                setNumeroChar(0);
                indexBits=i+1;
                indexFib=0;
                setUltimoSetado(true);
                return true;
            }
            if (bitSet.get(i)) {
                numeroChar += SEQFIBO[indexFib];
            }
            indexFib++;
        }
        indexBits=0;
        if (bitSet.get(15)){
            setUltimoSetado(true);
        }else setUltimoSetado(false);
        return false;
    }

     /**
     * @return the charSaida
     */
    public char getCharSaida() {
        return charSaida;
    }

    /**
     * @param charSaida the charSaida to set
     */
    public void setCharSaida(char charSaida) {
        this.charSaida = charSaida;
    }

    /**
     * @return the numeroChar
     */
    public int getNumeroChar() {
        return numeroChar;
    }

    /**
     * @param numeroChar the numeroChar to set
     */
    public void setNumeroChar(int numeroChar) {
        this.numeroChar = numeroChar;
    }

    /**
     * @return the ultimoSetado
     */
    public boolean isUltimoSetado() {
        return ultimoSetado;
    }

    /**
     * @param ultimoSetado the ultimoSetado to set
     */
    public void setUltimoSetado(boolean ultimoSetado) {
        this.ultimoSetado = ultimoSetado;
    }
}
